﻿// ....................................................................................................................
//	Author: Copyright (C) 2012 Ing. Marek Hubal
//	Email: hubal@acasoftware.org
// ....................................................................................................................

using System;

namespace core
{
    /// <summary>Trieda INodeList_LOCAL_ITEMS</summary>
    public class INodeList_LOCAL_ITEMS : INodeList
    {

        /// <summary>Trieda INodeComparer</summary>
        protected class INodeComparer : System.Collections.Generic.IComparer<INode>
        {
            protected delegate int OnCompare(INode N1, INode N2);
            protected OnCompare FCompareMethod; // Metoda porovnania

            /// <summary>Porovnanie podla nazvu asc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_0_Asc(INode N1, INode N2)
            {
                return string.Compare(((INodeData_LOCAL_ITEM)N1.NodeData).Name, ((INodeData_LOCAL_ITEM)N2.NodeData).Name);
            }
            /// <summary>Porovnanie podla nazvu desc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_0_Desc(INode N1, INode N2)
            {
                return -string.Compare(((INodeData_LOCAL_ITEM)N1.NodeData).Name, ((INodeData_LOCAL_ITEM)N2.NodeData).Name);
            }
            /// <summary>Porovnanie podla pripony asc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_1_Asc(INode N1, INode N2)
            {
                int R = string.Compare(N1.Ext, N2.Ext);
                if (R == 0) return Compare_0_Asc(N1, N2);
                else return R;
            }
            /// <summary>Porovnanie podla pripony desc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_1_Desc(INode N1, INode N2)
            {
                int R = -string.Compare(N1.Ext, N2.Ext);
                if (R == 0) return Compare_0_Desc(N1, N2);
                else return R;
            }
            /// <summary>Porovnanie podla velkosti asc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_2_Asc(INode N1, INode N2)
            {
                if (N1.Size == N2.Size) return Compare_0_Asc(N1, N2);
                return N1.Size > N2.Size ? 1 : -1;
            }
            /// <summary>Porovnanie podla velkosti desc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_2_Desc(INode N1, INode N2)
            {
                if (N1.Size == N2.Size) return Compare_0_Desc(N1, N2);
                return N1.Size > N2.Size ? -1 : 1;
            }
            /// <summary>Porovnanie podla datumu vytvorenia asc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_4_Asc(INode N1, INode N2)
            {
                int R = DateTime.Compare(((INodeData_LOCAL_ITEM)N1.NodeData).DCreate, ((INodeData_LOCAL_ITEM)N2.NodeData).DCreate);
                if (R == 0) return Compare_0_Asc(N1, N2);
                return R;
            }
            /// <summary>Porovnanie podla datumu vytvorenia desc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_4_Desc(INode N1, INode N2)
            {
                int R = -DateTime.Compare(((INodeData_LOCAL_ITEM)N1.NodeData).DCreate, ((INodeData_LOCAL_ITEM)N2.NodeData).DCreate);
                if (R == 0) return Compare_0_Desc(N1, N2);
                return R;
            }
            /// <summary>Porovnanie podla datumu posledneho zapisu asc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_5_Asc(INode N1, INode N2)
            {
                int R = DateTime.Compare(((INodeData_LOCAL_ITEM)N1.NodeData).DModify, ((INodeData_LOCAL_ITEM)N2.NodeData).DModify);
                if (R == 0) return Compare_0_Asc(N1, N2);
                return R;
            }
            /// <summary>Porovnanie podla datumu posledneho zapisu desc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_5_Desc(INode N1, INode N2)
            {
                int R = -DateTime.Compare(((INodeData_LOCAL_ITEM)N1.NodeData).DModify, ((INodeData_LOCAL_ITEM)N2.NodeData).DModify);
                if (R == 0) return Compare_0_Desc(N1, N2);
                return R;
            }
            /// <summary>Porovnanie podla datumu posledneho pristupu asc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_6_Asc(INode N1, INode N2)
            {
                int R = DateTime.Compare(((INodeData_LOCAL_ITEM)N1.NodeData).DLastAccess, ((INodeData_LOCAL_ITEM)N2.NodeData).DLastAccess);
                if (R == 0) return Compare_0_Asc(N1, N2);
                return R;
            }
            /// <summary>Porovnanie podla datumu posledneho pristupu desc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_6_Desc(INode N1, INode N2)
            {
                int R = -DateTime.Compare(((INodeData_LOCAL_ITEM)N1.NodeData).DLastAccess, ((INodeData_LOCAL_ITEM)N2.NodeData).DLastAccess);
                if (R == 0) return Compare_0_Desc(N1, N2);
                return R;
            }

            /// <summary>Konstruktor</summary>
            /// <param name="pCol">triediaci stlpec</param>
            /// <param name="pDirection">smer</param>
            public INodeComparer(int pCol, bool pDirection)
            {
                switch (pCol)
                {
                    case 6: if (pDirection) FCompareMethod = Compare_6_Asc; else FCompareMethod = Compare_6_Desc; break;
                    case 5: if (pDirection) FCompareMethod = Compare_5_Asc; else FCompareMethod = Compare_5_Desc; break;
                    case 4: if (pDirection) FCompareMethod = Compare_4_Asc; else FCompareMethod = Compare_4_Desc; break;
                    case 2: if (pDirection) FCompareMethod = Compare_2_Asc; else FCompareMethod = Compare_2_Desc; break;
                    case 1: if (pDirection) FCompareMethod = Compare_1_Asc; else FCompareMethod = Compare_1_Desc; break;
                    default: if (pDirection) FCompareMethod = Compare_0_Asc; else FCompareMethod = Compare_0_Desc; break;
                }
            }

            /// <summary>Compare metoda</summary>
            /// <param name="x">objekt 1</param>
            /// <param name="y">objekt 2</param>
            /// <returns>vysledok porovnania</returns>
            int System.Collections.Generic.IComparer<INode>.Compare(INode x, INode y)
            {
                return FCompareMethod(x, y); // Volam porovnavaciu metodu
            }
        }

        protected string FExpand_InitExpandPath; // Cesta na expandovanie
        protected IntPtr FExpand_Handle;
        protected System.Collections.Generic.List<INode> FExpand_Dirs;
        protected System.Collections.Generic.List<INode> FExpand_Files;
        protected long FExpand_MaxReadItemTime; // Maximalny cas nacitania zaznamu
        protected System.IO.FileSystemWatcher FWatchDog; // Objekt dohladu nad zmenou file systemu

        protected string FCopyModeBasePath; // Zakladna cesta pre copy mod
        protected IntPtr FCopyMode_FileHandle; // Handle suboru
        protected uint FCopyMode_FileAttributes; // Atributy suboru
        protected DateTime FCopyMode_DModify; // Datumn modifikacie suboru
        protected string FCopyMode_FileName; // Plny nazov suboru
        protected long FCopyMode_FileSize; // Aktualna velkost suboru
        protected System.IO.FileStream FCopyMode_FileStream; // Stream suboru pri nativnom spracovani

        public bool ExpandReparseLinks; // Priznak expandovania reparse linkov

        /// <summary>Otvorenie cache pre zapis</summary>
        /// <param name="pCacheID">ID cache</param>
        /// <returns>true / false</returns>
        protected override bool BeginWriteCache(string pCacheID)
        {
            return false;
        }
        /// <summary>Event: Changed pre FWatchDog</summary>
        /// <param name="pSender">sender</param>
        /// <param name="e">parameter</param>
        protected void Event_WatchDogChanged(object pSender, System.IO.FileSystemEventArgs e)
        {
            FWatchDog.EnableRaisingEvents = false; // Stop dalsie spustenie pri zmene
            FWasChanged = true;
        }
        /// <summary>Event: Renamed pre FWatchDog</summary>
        /// <param name="pSender">sender</param>
        /// <param name="e">parameter</param>
        protected void Event_WatchDogRenamed(object pSender, System.IO.RenamedEventArgs e)
        {
            FWatchDog.EnableRaisingEvents = false; // Stop next raise
            FWasChanged = true;
        }
        
        /// <summary>Konstruktor</summary>
        public INodeList_LOCAL_ITEMS(string pExpandPath = "")
        {
            // Inicializacia
            ID = NODE_LIST_ID_LOCAL_ITEMS;
            FColsCount = 8;
            FEnableVisibilityMask = 0xfe; FDefVisibilityMask = 0xff;
            FThreadExpandAvailable = true;
            FExpand_InitExpandPath = pExpandPath;
            FExpand_Handle = IntPtr.Zero;
            ExpandReparseLinks = true;
            FWatchDog = null;
            FCopyMode_FileHandle = IntPtr.Zero;
        }
        /// <summary>Dispose metoda</summary>
        public override void Dispose()
        {
            FWatchDog = (System.IO.FileSystemWatcher)ICore.DisposeObject(FWatchDog);
            base.Dispose(); // Volam predchodcu
        }

        /// <summary>Ziskanie nazvu stlpca</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>nazov alebo prazdny retazec</returns>
        public override string GetColumnName(int pIndex)
        {
            switch (pIndex)
            {
                case 0: return lang.NODE_LIST_LOCAL_ITEMS_TEXT_1;
                case 1: return lang.NODE_LIST_LOCAL_ITEMS_TEXT_2;
                case 2: return lang.NODE_LIST_LOCAL_ITEMS_TEXT_3;
                case 3: return lang.NODE_LIST_LOCAL_ITEMS_TEXT_4;
                case 4: return lang.NODE_LIST_LOCAL_ITEMS_TEXT_5;
                case 5: return lang.NODE_LIST_LOCAL_ITEMS_TEXT_6;
                case 6: return lang.NODE_LIST_LOCAL_ITEMS_TEXT_7;
                case 7: return lang.NODE_LIST_LOCAL_ITEMS_TEXT_8;
                default: return "";
            }
        }
        /// <summary>Ziskanie zarovnania stlpca</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>zarovnanie</returns>
        public override System.Windows.Forms.HorizontalAlignment GetColumnAlignment(int pIndex)
        {
            switch (pIndex)
            {
                case 2:
                    return System.Windows.Forms.HorizontalAlignment.Right;
                case 3:
                case 4:
                case 5:
                case 6:
                    return System.Windows.Forms.HorizontalAlignment.Center;
                default: return System.Windows.Forms.HorizontalAlignment.Left;
            }
        }
        /// <summary>Test ci sa node moze expandovat</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public override bool CanNodeExpand(int pIndex)
        {
            INode N = this[pIndex];
            if (N == null) return false; // Ziskam platny node

            switch (N.ID)
            {
                case INode.NODE_ID_LOCAL_ITEM:
                    {
                        if (N.IsDirectory) return true;
                        switch(IFileSystem.GetFileType(GetNodeExpandPath(pIndex))) 
                        {
                            case IFileSystem.FILE_TYPE_GZIP:
                            case IFileSystem.FILE_TYPE_TAR:
                            case IFileSystem.FILE_TYPE_TGZ:
                            case IFileSystem.FILE_TYPE_RAR:
                            case IFileSystem.FILE_TYPE_ZIP:
                                return true;
                            default: return false;
                        }
                    }
                default: return false;
            }
        }
        /// <summary>Test ci sa node moze otvorit</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public override bool CanNodeOpen(int pIndex)
        {
            INode N = this[pIndex];
            if (N == null) return false; // Ziskam platny node

            switch (N.ID)
            {
                case INode.NODE_ID_LOCAL_ITEM: return N.IsFile;
                default: return false;
            }
        }
        /// <summary>Ziskanie expandovacej cesty node</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>cesta</returns>
        public override string GetNodeExpandPath(int pIndex)
        {
            INode N = this[pIndex];
            if (N == null) return ""; // Ziskam platny node

            switch (N.ID)
            {
                case INode.NODE_ID_LOCAL_ITEM: return IFileSystem.AppendToPath(CurrentPath, N.Name);
                default: return "";
            }
        }
        /// <summary>Property: CurrentPath</summary>
        public override string CurrentPath
        {
            get
            {
                return FExpand_InitExpandPath;
            }
        }
        /// <summary>Property: KeyValue</summary>
        public override string KeyValue
        {
            get
            {
                return IFileSystem.ExtractName(CurrentPath).ToLower();
            }
        }
        /// <summary>Ziskanie volneho miesta na zariadeni</summary>
        public override long DeviceFreeSpace
        {
            get
            {
                try
                {
                    if (DeviceRootPath == "") return -1; // Nezmyselny root?

                    System.IO.DriveInfo Drv = new System.IO.DriveInfo(DeviceRootPath);
                    switch (Drv.DriveType)
                    {
                        case System.IO.DriveType.NoRootDirectory:
                        case System.IO.DriveType.Unknown:
                            return -1;
                        default: return Drv.IsReady ? Drv.AvailableFreeSpace : -1;
                    }
                    
                }
                catch
                {
                    return core2.GetDeviceFreeSpace(CurrentPath);
                }
            }
        }
        /// <summary>Property: DeviceRootPath</summary>
        public override string DeviceRootPath
        {
            get
            {
                return IFileSystem.ExtractDeviceRoot(CurrentPath);
            }
        }
        /// <summary>Test ci je mozne skryt stlpec</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public override bool CanHideColumn(int pIndex)
        {
            switch (pIndex)
            {
                case 0: return false;
                default: return true;
            }
        }
        /// <summary>Property: CanSort</summary>
        public override bool CanSort
        {
            get
            {
                return true;
            }
        }
        /// <summary>Test ci je mozne podla zadaneho stlpca triedit</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public override bool IsSortColumn(int pIndex)
        {
            switch (pIndex)
            {
                case 3:
                    return false;
                default: return true;
            }
        }
        /// <summary>Property: IsSlowDevice</summary>
        public override bool IsSlowDevice
        {
            get
            {
                return FExpand_MaxReadItemTime > 1000*1000;
            }
        }
        /// <summary>Property: CanSelect</summary>
        public override bool CanSelect
        {
            get
            {
                return true;
            }
        }
        /// <summary>Test moznosti oznacenia node</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        /// <summary>Test moznosti oznacenia node</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public override bool CanSelectNode(INode pNode)
        {
            if (pNode == null) return false; // Ziskam platny node

            switch (pNode.ID)
            {
                case INode.NODE_ID_BACK_ITEM: return false;
                default: return true;
            }
        }
        /// <summary>Property: CanShellCopy</summary>
        public override bool CanShellCopy
        {
            get 
            {
                return true;
            }
        }
        /// <summary>Property: CanShellPaste</summary>
        public override bool CanShellPaste
        {
            get 
            {
                return true;
            }
        }
        /// <summary>Property: CanShellCut</summary>
        public override bool CanShellCut
        {
            get
            {
                return true;
            }
        }
        /// <summary>Vytvorenie zakladnej tooltip informacie o node</summary>
        /// <param name="pNode">pozicia</param>
        /// <returns>vysledok</returns>
        public override string CreateBaseToolTipInfo(int pIndex)
        {
            INode N = this[pIndex]; // Ziskam node
            if (N == null) return ""; // Chyba?

            string P = GetNodeExpandPath(pIndex); // Ziskam plny nazov

            System.Text.StringBuilder B = new System.Text.StringBuilder();
            B.AppendFormat(lang.NODE_LIST_LOCAL_ITEMS_TEXT_12, P); B.AppendLine(); // Vyskladam info

            IWin32.SHFILEINFO shinfo = new IWin32.SHFILEINFO();
            if (IWin32.Shell32.SHGetFileInfo(P, 0, ref shinfo, (uint)System.Runtime.InteropServices.Marshal.SizeOf(shinfo), IWin32.SHGFI_TYPENAME) != IntPtr.Zero)
            {
                B.AppendFormat(lang.NODE_LIST_LOCAL_ITEMS_TEXT_12_1, shinfo.szTypeName); B.AppendLine();
            }
            B.AppendFormat(lang.NODE_LIST_LOCAL_ITEMS_TEXT_12_2, N.DCreate.ToString("dd.MM.yyyy HH:mm:ss")); B.AppendLine();
            B.AppendFormat(lang.NODE_LIST_LOCAL_ITEMS_TEXT_12_3, N.DLastModify.ToString("dd.MM.yyyy HH:mm:ss")); B.AppendLine();
            B.AppendFormat(lang.NODE_LIST_LOCAL_ITEMS_TEXT_12_4, N.DLastAccess.ToString("dd.MM.yyyy HH:mm:ss")); B.AppendLine();

            if (N.IsFile)
            {
                B.AppendFormat(lang.NODE_LIST_LOCAL_ITEMS_TEXT_12_5, ICore.Size2String((ulong)N.Size, 1)); B.AppendLine();
            }
            return B.ToString(); // Vratim vysledok
        }
        /// <summary>Vytvorenie rozsirenej tooltip informacie o node</summary>
        /// <param name="pNode">pozicia</param>
        /// <returns>vysledok</returns>
        public override string CreateExtendedToolTipInfo(int pIndex)
        {
            try
            {
                string P = GetNodeExpandPath(pIndex); // Ziskam plnu cestu
                System.Text.StringBuilder B = new System.Text.StringBuilder();

                Shell32.Shell shell = new Shell32.ShellClass(); // Extrahujem shell32 informacie
                Shell32.Folder folder = shell.NameSpace(IFileSystem.ExtractPath(P));
                Shell32.FolderItem folderItem = folder.ParseName(IFileSystem.ExtractName(P));

                B.Append(folder.GetDetailsOf(folderItem, -1)); B.AppendLine();

                folderItem = null; // Zrusim
                folder = null;
                shell = null;

                return B.ToString(); // Vratim vysledok
            }
            catch
            {
                return ""; // Chyba?
            }
        }
        /// <summary>Property: CanShellPrint</summary>
        public override bool CanShellPrint
        {
            get
            {
                return true;
            }
        }
        /// <summary>Ziskanie kapacity zariadenia</summary>
        public override long DeviceCapacity
        {
            get
            {
                try
                {
                    if (DeviceRootPath == "") return -1; // Nezmyselny root?

                    System.IO.DriveInfo Drv = new System.IO.DriveInfo(DeviceRootPath);
                    switch (Drv.DriveType)
                    {
                        case System.IO.DriveType.NoRootDirectory:
                        case System.IO.DriveType.Unknown:
                            return -1;
                        default: return Drv.IsReady ? Drv.TotalSize : -1;
                    }

                }
                catch
                {
                    return core2.GetDeviceCapacity(CurrentPath);
                }
            }
        }
        /// <summary>Ziskanie velkosti klustera zariadenia</summary>
        public override int DeviceClusterSize
        {
            get
            {
                return IFileSystem.GetDeviceClusterSize(CurrentPath);
            }
        }
        /// <summary>Property: CanCreateFolder</summary>
        public override bool CanCreateFolder
        {
            get
            {
                return true;
            }
        }
        /// <summary>Property: CanRename</summary>
        public override bool CanRename
        {
            get
            {
                return true;
            }
        }
        /// <summary>Test moznosti premenovania polozky</summary>
        public override bool CanRenameItem(int pIndex)
        {
            INode N = this[pIndex];
            if (N == null) return false; // Chyby node?

            switch (N.ID)
            {
                case INode.NODE_ID_BACK_ITEM: return false;
                default: return true;
            }
        }
        /// <summary>Property: IsCopySource</summary>
        public override bool IsCopySource
        {
            get
            {
                return true;
            }
        }
        /// <summary>Property: IsCopyDestination</summary>
        public override bool IsCopyDestination
        {
            get
            {
                if (IFileSystem.IsReadOnlyFileSystem(CurrentPath) == 1) return false;
                return true;
            }
        }
        /// <summary>Property: IsCopySourceItem</summary>
        public override bool IsCopySourceItem(int pIndex)
        {
            if (!IsCopySource) return false; // Test celku
            INode N = this[pIndex];
            if (N == null) return false; // Neplatny node?
            switch (N.ID)
            {
                case INode.NODE_ID_BACK_ITEM: return false;
                default: return true;
            }
        }
        /// <summary>Property: CanShellCopyItem</summary>
        public override bool CanShellCopyItem(int pIndex)
        {
            if (!CanShellCopy) return false; // Test celku
            INode N = this[pIndex];
            if (N == null) return false; // Neplatny node?
            switch (N.ID)
            {
                case INode.NODE_ID_BACK_ITEM: return false;
                default: return true;
            }
        }
        /// <summary>Property: CanTrash</summary>
        public override bool CanTrash
        {
            get
            {
                if (IFileSystem.IsReadOnlyFileSystem(CurrentPath) == 1) return false;
                return true;
            }
        }
        /// <summary>Property: CanTrashItem</summary>
        /// <param name="pIndex">pozicia</param>
        public override bool CanTrashItem(int pIndex)
        {
            if (!CanTrash) return false; // Test celeho zoznamu
            INode N = this[pIndex];
            if (N == null) return false; // Neplatny node?
            switch (N.ID)
            {
                case INode.NODE_ID_BACK_ITEM: return false;
                default: return true;
            }
        }
        /// <summary>Property: IsMoveSource</summary>
        public override bool IsMoveSource
        {
            get
            {
                if (IFileSystem.IsReadOnlyFileSystem(CurrentPath) == 1) return false;
                return true;
            }
        }
        /// <summary>Property: IsMoveSourceItem</summary>
        public override bool IsMoveSourceItem(int pIndex)
        {
            if (!IsMoveSource) return false; // Test celku
            INode N = this[pIndex];
            if (N == null) return false; // Neplatny node?
            switch (N.ID)
            {
                case INode.NODE_ID_BACK_ITEM: return false;
                default: return true;
            }
        }
        /// <summary>Property: CanShellCutItem</summary>
        public override bool CanShellCutItem(int pIndex)
        {
            if (!CanShellCut) return false; // Test celku
            INode N = this[pIndex];
            if (N == null) return false; // Neplatny node?
            switch (N.ID)
            {
                case INode.NODE_ID_BACK_ITEM: return false;
                default: return true;
            }
        }
        /// <summary>Property: CanDelete</summary>
        public override bool CanDelete
        {
            get
            {
                if (IFileSystem.IsReadOnlyFileSystem(CurrentPath) == 1) return false;
                return true;
            }
        }
        /// <summary>Property: CanDeleteItem</summary>
        /// <param name="pIndex">pozicia</param>
        public override bool CanDeleteItem(int pIndex)
        {
            if (!CanDelete) return false; // Test celeho zoznamu
            INode N = this[pIndex];
            if (N == null) return false; // Neplatny node?
            switch (N.ID)
            {
                case INode.NODE_ID_BACK_ITEM: return false;
                default: return true;
            }
        }
        /// <summary>Test ci node podporuje rychly presun poloziek na zadanu cestu</summary>
        /// <param name="pPath">cesta</param>
        /// <returns>true / false</returns>
        public override bool SupportFastMoveToPath(string pPath)
        {
            switch (IFileSystem._GetPathType(CurrentPath)) // Zdroj musi byt lokalna cesta
            {
                case IFileSystem.PATH_TYPE_LOCAL_FILE_SYSTEM:
                case IFileSystem.PATH_TYPE_LOCAL_FILE_SYSTEM_ROOT:
                    break;
                default: return false;
            }
            switch (IFileSystem._GetPathType(pPath)) // Ciel musi byt lokalna cesta
            {
                case IFileSystem.PATH_TYPE_LOCAL_FILE_SYSTEM:
                case IFileSystem.PATH_TYPE_LOCAL_FILE_SYSTEM_ROOT:
                    break;
                default: return false;
            }
            return string.Compare(IFileSystem.ExtractDeviceRoot(CurrentPath), IFileSystem.ExtractDeviceRoot(pPath), true) == 0; // Porovnam root
        }
        /// <summary>Test ci sa da node ako archiv extrahovat</summary>
        /// <param name="pIndex">pozicia node</param>
        /// <returns>true / false</returns>
        public override bool CanExtractArchiveNode(int pIndex)
        {
            INode N = this[pIndex];
            if (N == null) return false; // Neplatny node?
            switch (N.ID)
            {
                case INode.NODE_ID_BACK_ITEM: return false;
                default:
                    {
                        if (!N.IsFile) return false;
                        switch (IFileSystem.GetFileType(GetNodeExpandPath(pIndex)))
                        {
                            case IFileSystem.FILE_TYPE_GZIP:
                            case IFileSystem.FILE_TYPE_TAR:
                            case IFileSystem.FILE_TYPE_TGZ:
                            case IFileSystem.FILE_TYPE_RAR:
                            case IFileSystem.FILE_TYPE_ZIP:
                                return true;
                            default: return false;
                        }
                    }
            }
        }
        /// <summary>Test ci sa da node ako archiv otestovat</summary>
        /// <param name="pIndex">pozicia node</param>
        /// <returns>true / false</returns>
        public override bool CanTestArchiveNode(int pIndex)
        {
            return CanExtractArchiveNode(pIndex);
        }
        /// <summary>Property: CanChangeAttributes</summary>
        public override bool CanChangeAttributes
        {
            get
            {
                if (IFileSystem.IsReadOnlyFileSystem(CurrentPath) == 1) return false;
                return true;
            }
        }
        /// <summary>Test moznosti menit atributy node</summary>
        public override bool CanChangeAttributesNode(int pIndex)
        {
            if (!CanChangeAttributes) return false; // Test celku
            INode N = this[pIndex];
            if (N == null) return false; // Neplatny node?
            switch (N.ID)
            {
                case INode.NODE_ID_BACK_ITEM: return false;
                default: return true;
            }
        }
        /// <summary>Property: IsDragAndDropSource</summary>
        public override bool IsDragAndDropSource
        {
            get
            {
                return true;
            }
        }
        /// <summary>Property: SupportSearch</summary>
        public override bool SupportSearch
        {
            get
            {
                return true;
            }
        }
        /// <summary>Test moznosti vypoctu kontrolnych suctov</summary>
        public override bool CanCalcucateChecksum
        {
            get
            {
                return IsCopySource;
            }
        }
        /// <summary>Test moznosti vypoctu kontrolnych suctov polozky</summary>
        public override bool CanCalcucateChecksumItem(int pIndex)
        {
            return IsCopySourceItem(pIndex);
        }
        /// <summary>Test moznosti overenia kontrolnych suctov</summary>
        public override bool CanVerifyChecksum
        {
            get
            {
                return CanCalcucateChecksum;
            }
        }
        /// <summary>Test moznosti overenia kontrolnych suctov polozky</summary>
        public override bool CanVerifyChecksumItem(int pIndex)
        {
            return CanCalcucateChecksumItem(pIndex);
        }
        /// <summary>Test ci moze byt node prezerany</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public override bool CanNodeBeViewed(int pIndex)
        {
            INode N = this[pIndex];
            if (N == null) return false; // Neplatny node?
            switch (N.ID)
            {
                case INode.NODE_ID_LOCAL_ITEM: return N.IsFile;
                default: return false;
            }
        }
        /// <summary>Property: CanBeViewed</summary>
        public override bool CanBeViewed
        {
            get
            {
                return true;
            }
        }
        /// <summary>Test ci moze byt node editovany</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public override bool CanNodeBeEdited(int pIndex)
        {
            INode N = this[pIndex];
            if (N == null) return false; // Neplatny node?
            switch (N.ID)
            {
                case INode.NODE_ID_LOCAL_ITEM: return N.IsFile;
                default: return false;
            }
        }
        /// <summary>Property: CanMakeShortcut</summary>
        public override bool CanMakeShortcut
        {
            get
            {
                return true;
            }
        }
        /// <summary>Property: CanMakeShortcut</summary>
        public override bool CanNodeMakeShortcut(int pIndex)
        {
            if (!CanMakeShortcut) return false; // Test globalu
            INode N = this[pIndex];
            if (N == null) return false; // Neplatny node?
            switch (N.ID)
            {
                case INode.NODE_ID_LOCAL_ITEM: return true;
                default: return false;
            }
        }
        /// <summary>Test ci zoznam moze obsluzit zadanu cestu</summary>
        /// <param name="pPath">cesta</param>
        /// <returns>true / false</returns>
        public override bool CanServerPath(string pPath)
        {
            switch (IFileSystem._GetPathType(pPath))
            {
                case IFileSystem.PATH_TYPE_LOCAL_FILE_SYSTEM_ROOT:
                case IFileSystem.PATH_TYPE_LOCAL_FILE_SYSTEM:
                case IFileSystem.PATH_TYPE_SAMBA_FILE_SYSTEM:
                    return true;
                default: return false;
            }
        }
        /// <summary>Property: IsSourceForArchive</summary>
        public override bool IsSourceForArchive
        {
            get
            {
                return IsCopySource;
            }
        }
        /// <summary>Test ci je polozka zdrojom pre arechivaciu</summary>
        public override bool IsSourceForArchiveItem(int pIndex)
        {
            return IsCopySourceItem(pIndex);
        }
        /// <summary>Property: IsSourceForArchive</summary>
        public override bool IsDestinationForArchive
        {
            get
            {
                return IsCopyDestination;
            }
        }
        /// <summary>Property: IsEncryptionSource</summary>
        public override bool IsEncryptionSource
        {
            get
            {
                return IsCopySource;
            }
        }
        /// <summary>Test ci je node source pre sifrovanie</summary>
        public override bool IsEncryptionSourceItem(int pIndex)
        {
            return IsCopySourceItem(pIndex);
        }
        /// <summary>Property: IsEncryptionDestination</summary>
        public override bool IsEncryptionDestination
        {
            get
            {
                return IsCopyDestination;
            }
        }
        /// <summary>Property: IsDecryptionSource</summary>
        public override bool IsDecryptionSource
        {
            get
            {
                return IsCopySource;
            }
        }
        /// <summary>Test ci je node source pre desifrovanie</summary>
        public override bool IsDecryptionSourceItem(int pIndex)
        {
            return IsCopySourceItem(pIndex);
        }
        /// <summary>Property: IsDecryptionDestination</summary>
        public override bool IsDecryptionDestination
        {
            get
            {
                return IsCopyDestination;
            }
        }
        /// <summary>Property: CanRename</summary>
        public override bool CanMultiRename
        {
            get
            {
                return CanRename;
            }
        }
        /// <summary>Test moznosti premenovania polozky</summary>
        public override bool CanMultiRenameItem(int pIndex)
        {
            return CanRenameItem(pIndex);
        }
        
        /// <summary>Zaciatok expandovania obsahu</summary>
        /// <param name="pFilter">objekt filtra</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int BeginExpand(INodeFilters pFilter = null)
        {
            FExpand_Handle = IntPtr.Zero;
            FExpand_Dirs = new System.Collections.Generic.List<INode>();
            FExpand_Files = new System.Collections.Generic.List<INode>();
            FExpand_MaxReadItemTime = 0;

            if (ExpandReparseLinks) // Spracovat rep. linky?
            {
                if (IFileSystem.IsReparseLink(FExpand_InitExpandPath)) FExpand_InitExpandPath = IFileSystem.GetRaparseLink(FExpand_InitExpandPath); // Ak je rep. link tak ziskam fyzicku adresu
            }

            FState = 1; // Nastavim mode expand
            return 0;
        }
        /// <summary>Uzatvorenie aktualneho expandu</summary>
        public override void CloseExpand()
        {
            if (FExpand_Handle != IntPtr.Zero) IWin32.Kernel32.FindClose(FExpand_Handle); // Uzatvorim handle
            FExpand_Handle = IntPtr.Zero;

            for (int i = 0; i < FExpand_Dirs.Count; i++) AddNode(FExpand_Dirs[i]);
            for (int i = 0; i < FExpand_Files.Count; i++) AddNode(FExpand_Files[i]);

            FExpand_Dirs.Clear(); FExpand_Dirs = null;
            FExpand_Files.Clear(); FExpand_Files = null;
            FState = 0; // Nastavim normalny mod
            System.GC.Collect();
        }
        /// <summary>Expandovanie dalsieho zaznamu</summary>
        /// <param name="Result">ulozeny obsah najdeneho zaznamu alebo null ak sa ma zaznam pripojit do zoznamu</param>
        /// <returns>0 - ziaden dalsi zaznam, 1 - najdeny zaznam alebo kod chyby</returns>
        public override int ExpandNext(INodeFilters pFilter = null, INode Result = null)
        {
            try
            {
                INode N = Result == null ? new INode() : Result;
                IWin32.WIN32_FIND_DATA FindData = new IWin32.WIN32_FIND_DATA();

                //long FStart = DateTime.Now.Ticks; long T;

                if (FExpand_Handle == IntPtr.Zero)
                {
                    string P1 = IFileSystem.AppendToPath(FExpand_InitExpandPath, "*.*");
                    FExpand_Handle = IWin32.Kernel32.FindFirstFile(P1, out FindData); // Hladam prvy zaznam
                    if (FExpand_Handle.ToInt32() == IWin32.INVALID_HANDLE_VALUE) // Chyba?
                    {
                        int R = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                        switch (R)
                        {
                            case 2: // Specialny pripad
                                {
                                    INode N2 = new INode(); N2.ID = INode.NODE_ID_BACK_ITEM; AddNode(N2); // Vytvorim prvy back item node
                                    if (Result == null) N.Dispose(); // Zrusim objekt node
                                    return 0; // Ziaden dalsi zaznam
                                }
                            case 5: LastError = lang.NODE_LIST_LOCAL_ITEMS_TEXT_10_2; break;
                            case 21: LastError = lang.NODE_LIST_LOCAL_ITEMS_TEXT_10_1; break;
                            default: LastError = ""; break;
                        }
                        if (Result == null) N.Dispose(); // Zrusim objekt node
                        return -1; // Vratim chybu
                    }

                    //T = DateTime.Now.Ticks - FStart; if (T > FExpand_MaxReadItemTime) FExpand_MaxReadItemTime = T; // Ulozim maximalny cas
                    if (Result == null) { INode N1 = new INode(); N1.ID = INode.NODE_ID_BACK_ITEM; AddNode(N1); } // Vytvorim prvy back item node

                    bool B = true;
                    if ((B) && (FindData.cFileName == ".")) B = IWin32.Kernel32.FindNextFile(FExpand_Handle, out FindData); // Preskocim riadiace zaznamy
                    if ((B) && (FindData.cFileName == "..")) B = IWin32.Kernel32.FindNextFile(FExpand_Handle, out FindData);

                    if (!B) // Ziaden zaznam?
                    {
                        if (Result == null) N.Dispose(); // Zrusim objekt node
                        return 0; // Ziaden dalsi zaznam
                    }

                    N.ID = INode.NODE_ID_LOCAL_ITEM;
                    N.NodeData = new INodeData_LOCAL_ITEM();
                    ((INodeData_LOCAL_ITEM)N.NodeData).Attributes = FindData.dwFileAttributes;
                    ((INodeData_LOCAL_ITEM)N.NodeData).Size = FindData.nFileSizeHigh; ((INodeData_LOCAL_ITEM)N.NodeData).Size <<= 32; ((INodeData_LOCAL_ITEM)N.NodeData).Size += FindData.nFileSizeLow;
                    ulong L = (ulong)FindData.ftCreationTime.dwHighDateTime; L <<= 32; L |= (uint)FindData.ftCreationTime.dwLowDateTime;
                    ((INodeData_LOCAL_ITEM)N.NodeData).DCreate = DateTime.FromFileTime((long)L);
                    L = (ulong)FindData.ftLastWriteTime.dwHighDateTime; L <<= 32; L |= (uint)FindData.ftLastWriteTime.dwLowDateTime;
                    ((INodeData_LOCAL_ITEM)N.NodeData).DModify = DateTime.FromFileTime((long)L);
                    L = (ulong)FindData.ftLastAccessTime.dwHighDateTime; L <<= 32; L |= (uint)FindData.ftLastAccessTime.dwLowDateTime;
                    ((INodeData_LOCAL_ITEM)N.NodeData).DLastAccess = DateTime.FromFileTime((long)L);
                    ((INodeData_LOCAL_ITEM)N.NodeData).Name = FindData.cFileName;

                    if ((pFilter == null) || (pFilter.TestNode(N)))
                    {
                        if (Result == null)
                        {
                            if (N.IsDirectory) FExpand_Dirs.Add(N); else FExpand_Files.Add(N);
                        }
                        return 1; // Nasiel som zaznam
                    }
                    else FFilteredContent = true;
                }

                while (true)
                {
                    if (!IWin32.Kernel32.FindNextFile(FExpand_Handle, out FindData))
                    {
                        if (Result == null) N.Dispose(); // Zrusim objekt node
                        return 0; // Ziaden dalsi zaznam
                    }

                    //T = DateTime.Now.Ticks - FStart; if (T > FExpand_MaxReadItemTime) FExpand_MaxReadItemTime = T; // Ulozim maximalny cas

                    N.ID = INode.NODE_ID_LOCAL_ITEM;
                    N.NodeData = new INodeData_LOCAL_ITEM();
                    ((INodeData_LOCAL_ITEM)N.NodeData).Attributes = FindData.dwFileAttributes;
                    ((INodeData_LOCAL_ITEM)N.NodeData).Size = FindData.nFileSizeHigh; ((INodeData_LOCAL_ITEM)N.NodeData).Size <<= 32; ((INodeData_LOCAL_ITEM)N.NodeData).Size += FindData.nFileSizeLow;
                    ulong L = (ulong)FindData.ftCreationTime.dwHighDateTime; L <<= 32; L |= (uint)FindData.ftCreationTime.dwLowDateTime;
                    ((INodeData_LOCAL_ITEM)N.NodeData).DCreate = DateTime.FromFileTime((long)L);
                    L = (ulong)FindData.ftLastWriteTime.dwHighDateTime; L <<= 32; L |= (uint)FindData.ftLastWriteTime.dwLowDateTime;
                    ((INodeData_LOCAL_ITEM)N.NodeData).DModify = DateTime.FromFileTime((long)L);
                    L = (ulong)FindData.ftLastAccessTime.dwHighDateTime; L <<= 32; L |= (uint)FindData.ftLastAccessTime.dwLowDateTime;
                    ((INodeData_LOCAL_ITEM)N.NodeData).DLastAccess = DateTime.FromFileTime((long)L);
                    ((INodeData_LOCAL_ITEM)N.NodeData).Name = FindData.cFileName;

                    if ((pFilter == null) || (pFilter.TestNode(N)))
                    {
                        if (Result == null)
                        {
                            if (N.IsDirectory) FExpand_Dirs.Add(N); else FExpand_Files.Add(N);
                            if (ProgressMessage != null) ProgressMessage.StringValue = string.Format(lang.NODE_LIST_LOCAL_ITEMS_TEXT_11, FExpand_Dirs.Count + FExpand_Files.Count);
                        }
                        return 1; // Nasiel som zaznam
                    }
                    else FFilteredContent = true;
                }
            }
            catch
            {
                return -1;
            }
        }
        /// <summary>Vytvorenie textov pre zobrazenie</summary>
        /// <param name="pNode">objekt node</param>
        public override void CreateDisplayStrings(INode pNode)
        {
            if (pNode.DisplayStrings != null) return; // Uz su vytvorenie?

            pNode.DisplayStrings = new string[ColsCount]; // Alokujem retazec
            switch (pNode.ID) // Podla typu node
            {
                case INode.NODE_ID_BACK_ITEM:
                    {
                        pNode.DisplayStrings[0] = ICore.BoundString("[", "..", "]", IApp.Settings.FileExplorer_DirsInBraces);
                        pNode.DisplayStrings[2] = lang.NODE_LIST_LOCAL_ITEMS_TEXT_9_1;
                        pNode.DefaultImageIndex = -1;
                    } break;
                case INode.NODE_ID_LOCAL_ITEM:
                    {
                        if (pNode.IsDirectory)
                        {
                            pNode.DisplayStrings[0] = ICore.BoundString("[", pNode.Name, "]", IApp.Settings.FileExplorer_DirsInBraces);
                            if (pNode.ValidSize) pNode.DisplayStrings[2] = ICore.Size2String((ulong)pNode.Size, IApp.Settings.FileExplorer_DisplaySizeMode);
                            else pNode.DisplayStrings[2] = lang.NODE_LIST_LOCAL_ITEMS_TEXT_9_2;
                            pNode.DefaultImageIndex = 0; // Default ikona
                        }
                        else
                        {
                            pNode.DisplayStrings[0] = pNode.NameOnly; // Len nazov
                            if (pNode.DisplayStrings[0] == "") pNode.DisplayStrings[0] = pNode.Name; else pNode.DisplayStrings[1] = pNode.Ext; // Pripona
                            pNode.DisplayStrings[2] = ICore.Size2String((ulong)pNode.Size, IApp.Settings.FileExplorer_DisplaySizeMode); // Velkost
                            pNode.DefaultImageIndex = 1; // Default ikona
                        }
                        pNode.DisplayStrings[3] = pNode.AttributesAsString;
                        pNode.DisplayStrings[4] = ICore.DateTime2Str(pNode.DCreate);
                        pNode.DisplayStrings[5] = ICore.DateTime2Str(pNode.DLastModify);
                        pNode.DisplayStrings[6] = ICore.DateTime2Str(pNode.DLastAccess);
                    } break;
            }
        }
        /// <summary>Triedenie obsahu zoznamu</summary>
        /// <param name="pColumn">stlpec</param>
        /// <param name="pAsc">smer</param>
        public override void Sort(int pColumn, bool pAsc)
        {
            int S = IsBackNode(0) ? 1 : 0; // Urcim zaciatok
            if (DirsCount > 1)
            {
                FItems.Sort(S, DirsCount, new INodeComparer(0, pAsc));
            }
            if (FilesCount > 1)
            {
                FItems.Sort(S + DirsCount, FilesCount, new INodeComparer(pColumn, pAsc));
            }
        }
        /// <summary>Spustenie dozerania na zmenu obsahu</summary>
        public override void StartChangedWatch()
        {
            FWatchDog = (System.IO.FileSystemWatcher)ICore.DisposeObject(FWatchDog);
            try
            {
                FWatchDog = new System.IO.FileSystemWatcher(CurrentPath); // Vytvorim a spustim sledovanie
                FWatchDog.NotifyFilter = System.IO.NotifyFilters.DirectoryName | System.IO.NotifyFilters.FileName; // Nastavim co budem sledovat
                FWatchDog.Filter = "*.*"; // Sledujem vsetko
                FWatchDog.Created += Event_WatchDogChanged;
                FWatchDog.Deleted += Event_WatchDogChanged;
                FWatchDog.Renamed += Event_WatchDogRenamed;
                FWatchDog.EnableRaisingEvents = true;
                FWasChanged = false;
            }
            catch
            {
                FWatchDog = (System.IO.FileSystemWatcher)ICore.DisposeObject(FWatchDog);
            }
        }
        /// <summary>Zastavenie dozerania na zmenu obsahu</summary>
        public override void StopChangedWatch()
        {
            if (FWatchDog != null)
            {
                FWatchDog.EnableRaisingEvents = false;
                FWatchDog = (System.IO.FileSystemWatcher)ICore.DisposeObject(FWatchDog);
            }
        }
        /// <summary>Property: CanCloneFile</summary>
        public override bool CanCloneFile
        {
            get
            {
                return true;
            }
        }
        /// <summary>Property: CanCreateEmptyFile</summary>
        public override bool CanCreateEmptyFile
        {
            get
            {
                return IsCopyDestination;
            }
        }
        /// <summary>Vytvorenie klonu zoznamu</summary>
        /// <returns>objekt zoznamu</returns>
        public override INodeList CloneList()
        {
            return new INodeList_LOCAL_ITEMS(CurrentPath);
        }

        /// <summary>Spustenie mazania zaznamov</summary>
        /// <param name="pItems">zoznam objektov</param>
        /// <param name="pProgressForm">progress okno</param>
        /// <param name="pStatData">statisticke data pre vypocet stavu</param>
        public override bool Run_DeleteItems(System.Collections.Generic.List<string> pItems, IFileExplorer_ProgressForm_DeleteItems pProgressForm = null, IComputeOccupiedSpaceData pStatData = null)
        {
            IConfirmationFlags Flags = new IConfirmationFlags(); // Priznaky potvrdeni uzivatela

            foreach (string FN in pItems) // Vsetky polozky
            {
                if (IFileSystem.IsReparseLink(FN)) continue; // Preskakujem reparse link

                int R = IFileSystem.GetObjectType(FN);
                if (R == IFileSystem.OBJECT_TYPE_FILE)
                {
                    if (DeleteNodeFile(FN, Flags, pProgressForm) < 0) return false; // Volam vymazanie suboru
                    continue;
                }

                if (R == IFileSystem.OBJECT_TYPE_DIRECTORY)
                {
                    if (DeleteNodeDirectory(FN, Flags, pProgressForm) < 0) return false; // Volam vymazanie priecinku
                    continue;
                }
            }
            return true; // Vsetko OK
        }
        /// <summary>Vymazanie suboru</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pFlags">objekt volieb</param>
        /// <param name="pProgressForm">formular pre progress</param>
        /// <returns>0 - OK, 1 - preskocene, -1 - uzivatelsky prerusene</returns>
        protected int DeleteNodeFile(string pName, IConfirmationFlags pFlags, IFileExplorer_ProgressForm_DeleteItems pProgressForm = null)
        {
            if (pFlags.DeleteErrorFile != IConfirmationFlags.DELETE_ERROR_SKIP_ALL) pFlags.DeleteErrorFile = -1;
            if ((pFlags.DeleteReadOnlyFile != IConfirmationFlags.DELETE_READ_ONLY_YES_ALL) && (pFlags.DeleteReadOnlyFile != IConfirmationFlags.DELETE_READ_ONLY_SKIP_ALL)) pFlags.DeleteReadOnlyFile = -1;
            if ((pFlags.DeleteSystemFile != IConfirmationFlags.DELETE_SYSTEM_YES_ALL) && (pFlags.DeleteSystemFile != IConfirmationFlags.DELETE_SYSTEM_SKIP_ALL)) pFlags.DeleteSystemFile = -1;

            while (true)
            {
                if ((pProgressForm != null) && (pProgressForm.WaitForTerminate.BoolValue)) return -1;
                int R = IFileSystem.DeleteFile(pName, pFlags.ForceDeleteReadOnly, pFlags.ForceDeleteSystem, pFlags.ForceDeleteSystem); // Volam mazanie suboru
                switch (R)
                {
                    case 0:
                        {
                            if (pProgressForm != null) pProgressForm.AddFile();
                            return 0; // Vsetko OK
                        }
                    case IFileSystem.FS_ERROR_SYSTEM_ATTRIBUTE:
                    case IFileSystem.FS_ERROR_HIDDEN_ATTRIBUTE:
                        {
                            if (pProgressForm == null) return 1; // Nie je form?
                            switch (pFlags.DeleteSystemFile)
                            {
                                case IConfirmationFlags.DELETE_SYSTEM_YES:
                                case IConfirmationFlags.DELETE_SYSTEM_YES_ALL:
                                    break;
                                case IConfirmationFlags.DELETE_SYSTEM_SKIP:
                                case IConfirmationFlags.DELETE_SYSTEM_SKIP_ALL:
                                    return 1;
                                default:
                                    {
                                        if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_19_9_1, pName), lang.FILE_EXPLORER_TEXT_19_9_2, lang.FILE_EXPLORER_TEXT_19_9_3, ref pFlags.DeleteSystemFile)) return -1;
                                    } break;
                            }
                        } break;
                    case IFileSystem.FS_ERROR_READ_ONLY_ATTRIBUTE:
                        {
                            if (pProgressForm == null) return 1; // Nie je form?
                            switch(pFlags.DeleteReadOnlyFile) 
                            {
                                case IConfirmationFlags.DELETE_READ_ONLY_YES:
                                case IConfirmationFlags.DELETE_READ_ONLY_YES_ALL:
                                    break;
                                case IConfirmationFlags.DELETE_READ_ONLY_SKIP:
                                case IConfirmationFlags.DELETE_READ_ONLY_SKIP_ALL:
                                    return 1;
                                default: 
                                {
                                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_19_8_1, pName), lang.FILE_EXPLORER_TEXT_19_8_2, lang.FILE_EXPLORER_TEXT_19_8_3, ref pFlags.DeleteReadOnlyFile)) return -1;
                                } break;
                            }
                        } break;
                    default:
                        {
                            if (pProgressForm == null) return 1; // Nie je form?
                            switch(pFlags.DeleteErrorFile) 
                            {
                                case IConfirmationFlags.DELETE_ERROR_SKIP:
                                case IConfirmationFlags.DELETE_ERROR_SKIP_ALL:
                                    return 1;
                                default: 
                                {
                                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_19_7_1, pName), lang.FILE_EXPLORER_TEXT_19_7_2, lang.FILE_EXPLORER_TEXT_19_7_3, ref pFlags.DeleteErrorFile)) return -1;
                                } break;
                            }
                        } break;
                }
            }
        }
        /// <summary>Vymazanie priecinku</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pFlags">objekt volieb</param>
        /// <param name="pProgressForm">formular pre progress</param>
        /// <returns>0 - OK, 1 - preskocene, -1 - uzivatelsky prerusene</returns>
        protected int DeleteNodeDirectory(string pName, IConfirmationFlags pFlags, IFileExplorer_ProgressForm_DeleteItems pProgressForm = null)
        {
            if ((pFlags.DeleteNotEmptyFolder != IConfirmationFlags.DELETE_NOT_EMPTY_FOLDER_SKIP_ALL) && (pFlags.DeleteNotEmptyFolder != IConfirmationFlags.DELETE_NOT_EMPTY_FOLDER_YES_ALL)) pFlags.DeleteNotEmptyFolder = -1;

            INodeList L = INodeList.CreateNodeList(pName); // Vytvorim nodelist
            if (L == null) return 0;

            int State = 0; bool FirstNode = true;
            using (INode N = new INode())
            {
                using (L)
                {
                    if (L.BeginExpand() != 0) return 0;
                    while (true)
                    {
                        int R = L.ExpandNext(null, N);
                        if (R != 1) break;

                        if (FirstNode)
                        {
                            while (true)
                            {
                                switch (pFlags.DeleteNotEmptyFolder)
                                {
                                    case IConfirmationFlags.DELETE_NOT_EMPTY_FOLDER_YES:
                                    case IConfirmationFlags.DELETE_NOT_EMPTY_FOLDER_YES_ALL:
                                        break;
                                    case IConfirmationFlags.DELETE_NOT_EMPTY_FOLDER_SKIP:
                                    case IConfirmationFlags.DELETE_NOT_EMPTY_FOLDER_SKIP_ALL:
                                        return 1;
                                    default:
                                        {
                                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_19_10_1, pName), lang.FILE_EXPLORER_TEXT_19_10_2, lang.FILE_EXPLORER_TEXT_19_10_3, ref pFlags.DeleteNotEmptyFolder)) return -1;
                                        } break;
                                }
                                if (pFlags.DeleteNotEmptyFolder <= IConfirmationFlags.DELETE_NOT_EMPTY_FOLDER_YES_ALL) break;
                            }
                            FirstNode = false;
                        }

                        string FN = IFileSystem.AppendToPath(L.CurrentPath, N.Name);
                        int State1 = 0;
                        switch (IFileSystem.GetObjectType(FN))
                        {
                            case IFileSystem.OBJECT_TYPE_FILE: State1 = DeleteNodeFile(FN, pFlags, pProgressForm); break;
                            case IFileSystem.OBJECT_TYPE_DIRECTORY: State1 = DeleteNodeDirectory(FN, pFlags, pProgressForm); break;
                            default: State1 = 1; break;
                        }
                        if (State1 == -1) return -1; // Presusene?
                        if (State1 == 1) State = 1; // Aktualizujem celkovy stav
                    }
                    L.CloseExpand();
                }
            }

            if (State == 0)
            {
                while (true)
                {
                    int R = IFileSystem.DeleteDirectory(pName);
                    switch (R)
                    {
                        case 0:
                            {
                                if (pProgressForm != null) pProgressForm.AddDir();
                                return 0; // Vsetko OK
                            }
                        default:
                            {
                                if (pProgressForm == null) return 1; // Nie je form?
                                switch (pFlags.DeleteErrorFolder)
                                {
                                    case IConfirmationFlags.DELETE_ERROR_SKIP:
                                    case IConfirmationFlags.DELETE_ERROR_SKIP_ALL:
                                        return 1;
                                    default:
                                        {
                                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_19_11_1, pName), lang.FILE_EXPLORER_TEXT_19_11_2, lang.FILE_EXPLORER_TEXT_19_11_3, ref pFlags.DeleteErrorFolder)) return -1;
                                        } break;
                                }
                            } break;
                    }
                }
            }
            return 1; // Preskoceny priecinok
        }

        /// <summary>Spustenie zmeny atributov zaznamov</summary>
        /// <param name="pChangeData">data pre zmenu</param>
        /// <param name="pItems">zoznam objektov</param>
        /// <param name="pProgressForm">progress okno</param>
        /// <param name="pStatData">statisticke data pre vypocet stavu</param>
        public override bool Run_ChangeItemsAttributes(IAttributeChangeDataObject pChangeData, System.Collections.Generic.List<string> pItems, IFileExplorer_ProgressForm_ChangeItemsAttributes pProgressForm = null, IComputeOccupiedSpaceData pStatData = null)
        {
            DateTime D1 = DateTime.MinValue, D2 = DateTime.MinValue, D3 = DateTime.MinValue;
            uint Attr;

            foreach (string FN in pItems) // Vsetky polozky
            {
                if (IFileSystem.IsReparseLink(FN)) continue; // Preskakujem reparse link

                if ((pProgressForm != null) && (pProgressForm.WaitForTerminate.BoolValue)) return false; // Prerusenie?

                int R = IFileSystem.GetObjectType(FN);
                if (R == IFileSystem.OBJECT_TYPE_FILE)
                {
                    if (IFileSystem.GetAttributes(FN, out Attr) == 0) // Ziskam aktualne atributy
                    {
                        pChangeData.ApplyValues(ref Attr, ref D1, ref D2, ref D3); // Aplikujem zmeny
                        IFileSystem.SetAttributes(FN, Attr, D1, D2, D3); // Nastavim nove
                    }
                    if (pProgressForm != null) pProgressForm.AddFile();
                    continue;
                }

                if (R == IFileSystem.OBJECT_TYPE_DIRECTORY)
                {
                    if (SetDirAttributes(pChangeData, FN, pProgressForm) == 1) return false; // Volam zmenu priecinku
                    continue;
                }
            }
            return true; // Vsetko OK
        }
        /// <summary>Nastavenie atributov priecinku</summary>
        /// <param name="pChangeData">data zmeny</param>
        /// <param name="pName">nazov</param>
        /// <param name="pProgressForm">formular</param>
        /// <returns>0 - OK, 1 - zrusenie</returns>
        protected int SetDirAttributes(IAttributeChangeDataObject pChangeData, string pName, IFileExplorer_ProgressForm_ChangeItemsAttributes pProgressForm = null)
        {
            DateTime D1 = DateTime.MinValue, D2 = DateTime.MinValue, D3 = DateTime.MinValue;
            uint Attr;

            if (pChangeData.ApplyToSubfolders)
            {
                using (INode N = new INode())
                {
                    INodeList L = INodeList.CreateNodeList(pName);
                    if (L != null)
                    {
                        using (L)
                        {
                            if (L.BeginExpand() == 0)
                            {
                                while (true)
                                {
                                    if ((pProgressForm != null) && (pProgressForm.WaitForTerminate.BoolValue)) return 1; // Prerusenie?

                                    if (L.ExpandNext(null, N) != 1) break;

                                    string FN = IFileSystem.AppendToPath(L.CurrentPath, N.Name);
                                    if (N.IsFile)
                                    {
                                        if (IFileSystem.GetAttributes(FN, out Attr) == 0) // Ziskam aktualne atributy
                                        {
                                            pChangeData.ApplyValues(ref Attr, ref D1, ref D2, ref D3); // Aplikujem zmeny
                                            IFileSystem.SetAttributes(FN, Attr, D1, D2, D3); // Nastavim nove
                                        }
                                        if (pProgressForm != null) pProgressForm.AddFile();
                                    }
                                    if (N.IsDirectory)
                                    {
                                        if (SetDirAttributes(pChangeData, FN, pProgressForm) == 1) return 1; // Volam zmenu priecinku
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (IFileSystem.GetAttributes(pName, out Attr) == 0) // Ziskam aktualne atributy
            {
                pChangeData.ApplyValues(ref Attr, ref D1, ref D2, ref D3); // Aplikujem zmeny
                IFileSystem.SetAttributes(pName, Attr, D1, D2, D3); // Nastavim nove
            }
            if (pProgressForm != null) pProgressForm.AddDir();
            return 0;
        }

        /// <summary>Spustenie hladania nad zoznamom</summary>
        /// <param name="pData">udaje pre hladanie</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public override bool Run_Search(ISearchDataStruct pData, int pDepth, IFileExplorer_ProgressForm_Search pProgressForm = null)
        {
            if (BeginExpand() != 0) return true; // Chyba zaciatku expandu?

            using (INode N = new INode())
            {
                while (true)
                {
                    if ((pProgressForm != null) && (pProgressForm.CanCancelSearch)) return false;

                    int R = ExpandNext(null, N);
                    if (R != 1) break; // Koniec alebo chyba?
                    
                    string FullPath = IFileSystem.AppendToPath(CurrentPath, N.Name);
                    if (IFileSystem.IsReparseLink(FullPath)) continue;

                    if (pProgressForm != null) pProgressForm.SetCurrentSearchItem(FullPath);
                    if (N.IsDirectory) // Priecinok?
                    {
                        if ((!pData.SearchInContent) || (pData.SearchContentValue == "")) // V pripade hladania v obsahu sa priecinky do vysledku nezaradia
                        {
                            if (pData.SearchPartialName) // Hladat cast mena?
                            {
                                if ((pData.SearchNameValue == "") || (INodeFilter.WildcardMatch(N.Name.ToLower(), pData.SearchNameValue.ToLower()))) // Porovnam ako wildcards
                                {
                                    if (pData.SearchExtFilter.TestNode(N)) // Test filtra
                                    {
                                        if (pProgressForm != null) pProgressForm.AddResult(FullPath, 0, true, N.Attributes, N.DLastModify, false, N.ID); // Zaradim ako vysledok hladania
                                    }
                                }
                            }
                            else
                            {
                                if ((pData.SearchNameValue == "") || (string.Compare(N.Name, pData.SearchNameValue, true) == 0)) // Porovnam presne s menom
                                {
                                    if (pData.SearchExtFilter.TestNode(N)) // Testujem filter
                                    {
                                        if (pProgressForm != null) pProgressForm.AddResult(FullPath, 0, true, N.Attributes, N.DLastModify, false, N.ID); // Zaradim ako vysledok hladania
                                    }
                                }
                            }
                        }

                        if ((pData.SearchMaxDepth == -1) || (pDepth < pData.SearchMaxDepth)) // Budem hladat aj v dalsej podurovni?
                        {
                            INodeList L = INodeList.CreateNodeList(FullPath); // Vytvorim list
                            if (L != null) // Ak je platny
                            {
                                using (L)
                                {
                                    if (!L.Run_Search(pData, pDepth + 1, pProgressForm)) return false; // Volam hladanie
                                }
                            }
                        }
                    }
                    else // Hladam v subore
                    {
                        bool IsIn = false; // Priznak platneho testu nazvu
                        if (pData.SearchPartialName) // Cast mena
                        {
                            if ((pData.SearchNameValue == "") || (INodeFilter.WildcardMatch(N.Name.ToLower(), pData.SearchNameValue.ToLower()))) // Wildcars porovnanie
                            {
                                if (pData.SearchExtFilter.TestNode(N)) // Test filtra
                                {
                                    if (!pData.SearchInContent) // Nehladat v obsahu
                                    {
                                        if (pProgressForm != null) pProgressForm.AddResult(FullPath, N.Size, false, N.Attributes, N.DLastModify, false, N.ID); // Zaradim ako vysledok hladania
                                    }
                                    IsIn = true; // Oznacim ze presiel
                                }
                            }
                        }
                        else
                        {
                            if ((pData.SearchNameValue == "") || (string.Compare(N.Name, pData.SearchNameValue, true) == 0)) // Test plneho mena
                            {
                                if (pData.SearchExtFilter.TestNode(N)) // Test filtra
                                {
                                    if (!pData.SearchInContent) // Nehladat v obsahu?
                                    {
                                        if (pProgressForm != null) pProgressForm.AddResult(FullPath, N.Size, false, N.Attributes, N.DLastModify, false, N.ID); // Zaradim ako vysledok hladania
                                    }
                                    IsIn = true; // Oznacim ze presiel
                                }
                            }
                        }

                        if ((pData.SearchInArchive) && ((pData.SearchMaxDepth == -1) || (pDepth < pData.SearchMaxDepth))) // Hladat v archivoch?
                        {
                            INodeList L = INodeList.CreateNodeList(FullPath); // Vytvorim list pre archiv
                            if (L != null) // Ak je platny
                            {
                                if (!L.Run_Search(pData, pDepth + 1, pProgressForm)) return false; // Spustim hladanie
                            }
                        }
                        else // Nie je to archiv
                        {
                            if ((IsIn) && (pData.SearchInContent)) // Prehladavat obsah?
                            {
                                if (string.IsNullOrEmpty(pData.SearchContentValue)) // Hladana hodnota je prazdna? - obsah sa prehlasi za true
                                {
                                    if (!pData.SearchInContent_NotInContent) // Zaradovat true?
                                    {
                                        if (pProgressForm != null) pProgressForm.AddResult(FullPath, N.Size, false, N.Attributes, N.DLastModify, false, N.ID); // Zaradim ako vysledok hladania
                                    }
                                }
                                else
                                {
                                    // Idem prehladavat obsah
                                    using (ISearchInContentStream CntStream = new ISearchInContentStream()) // Vytvorim hladaci stream
                                    {
                                        try
                                        {
                                            using (System.IO.FileStream FS = new System.IO.FileStream(FullPath, System.IO.FileMode.Open, System.IO.FileAccess.Read)) // Otvorim subor na citanie
                                            {
                                                CntStream.Init(pData.SearchContentValue, pData.SearchInContent_CaseSensitive, pData.SearchInContent_EncodingType); // Inicializujem stream
                                                CntStream.GetData += (pBuffer, pStart, pMaxLength) => // Event na dodanie dat streamu
                                                    {
                                                        try
                                                        {
                                                            return FS.Read(pBuffer, pStart, pMaxLength);
                                                        }
                                                        catch
                                                        {
                                                            return 0;
                                                        }
                                                    };
                                                int Res = CntStream.Find(pProgressForm); // Hladam
                                                if (Res == ISearchInContentStream.FIND_YES) // Nasiel som?
                                                {
                                                    if (!pData.SearchInContent_NotInContent) // Zaradoivat true vysledky?
                                                    {
                                                        if (pProgressForm != null) pProgressForm.AddResult(FullPath, N.Size, false, N.Attributes, N.DLastModify, false, N.ID); // Zaradim ako vysledok hladania
                                                    }
                                                }
                                                else // Nenasiel som
                                                {
                                                    if (pData.SearchInContent_NotInContent) // Zaradovat false vysledky?
                                                    {
                                                        if (pProgressForm != null) pProgressForm.AddResult(FullPath, N.Size, false, N.Attributes, N.DLastModify, false, N.ID); // Zaradim ako vysledok hladania
                                                    }
                                                }
                                            }
                                        }
                                        catch // Pri chybe jednoducho nic nezaradim
                                        {
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            CloseExpand(); // Uzatvorim expand
            return true;
        }
        /// <summary>Spustenie procesu klonovania suboru</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pNewName">novy nazov</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public override bool Run_CloneFile(string pName, string pNewName, IFileExplorer_ProgressForm_CloneFile pProgressForm = null)
        {
            System.IO.FileStream InputFile; // Zdrojovy subor
            System.IO.FileStream OutputFile; // Cielovy subor
            int R;
            bool DeleteResult = false;

            try
            {
                while (true) // Otvorim zdrojovy subor
                {
                    try
                    {
                        InputFile = new System.IO.FileStream(pName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                        break;
                    }
                    catch
                    {
                        if (pProgressForm != null)
                        {
                            R = 0;
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_38_5_1, pName), lang.FILE_EXPLORER_TEXT_38_5_2, lang.FILE_EXPLORER_TEXT_38_5_3, ref R)) return false; // Opytam sa na zopakovanie
                        }
                        else return false;
                    }
                }

                using (InputFile)
                {

                    while (true) // Vytvorim cielovy subor
                    {
                        try
                        {
                            OutputFile = new System.IO.FileStream(pNewName, System.IO.FileMode.Create, System.IO.FileAccess.Write);
                            break;
                        }
                        catch
                        {
                            if (pProgressForm != null)
                            {
                                R = 0;
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_38_6_1, pNewName), lang.FILE_EXPLORER_TEXT_38_6_2, lang.FILE_EXPLORER_TEXT_38_6_3, ref R)) return false; // Opytam sa na zopakovanie
                            }
                            else return false;
                        }
                    }

                    int C;
                    using (OutputFile)
                    {
                        byte[] Buffer = new byte[MAX_COPY_BUFFER_SIZE];
                        while (true)
                        {
                            if ((pProgressForm != null) && (pProgressForm.WaitForTerminate.BoolValue)) // Prerusenie?
                            {
                                DeleteResult = true;
                                break;
                            }
                            while (true) // Nacitam data
                            {
                                try
                                {
                                    C = InputFile.Read(Buffer, 0, MAX_COPY_BUFFER_SIZE);
                                    break;
                                }
                                catch
                                {
                                    R = 0;
                                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_38_7_1, pName), lang.FILE_EXPLORER_TEXT_38_7_2, lang.FILE_EXPLORER_TEXT_38_7_3, ref R)) // Opytam sa na zopakovanie
                                    {
                                        DeleteResult = true;
                                        C = 0;
                                        break;
                                    }
                                }
                            }
                            if (C == 0) break; // Koniec?
                            
                            while (true) // Zapisem data
                            {
                                try
                                {
                                    OutputFile.Write(Buffer, 0, C);
                                    break;
                                }
                                catch
                                {
                                    R = 0;
                                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_38_8_1, pNewName), lang.FILE_EXPLORER_TEXT_38_8_2, lang.FILE_EXPLORER_TEXT_38_8_3, ref R)) // Opytam sa na zopakovanie
                                    {
                                        DeleteResult = true;
                                        break;
                                    }
                                }
                            }

                            if (pProgressForm != null) pProgressForm.AddProcessedData(C); // Aktualizujem stav
                        }
                    }
                }

                if (DeleteResult) IFileSystem.DeleteFile(pNewName, true, true, true); // Mam vymazat vysledok?
                else
                {
                    uint Attr;
                    DateTime D1, D2, D3;
                    if (IFileSystem.GetAttributes(pName, out Attr, out D1, out D2, out D3) == 0) IFileSystem.SetAttributes(pNewName, Attr, D1, D2, D3); // Nastavim atributy
                }

                return true;
            }
            catch
            {
                return false; // Chyba
            }
        }

        /// <summary>Vytvorenie odkazu na zadany objekt</summary>
        /// <param name="pName">plny nazov</param>
        /// <param name="pSourceName">zdrojovy nazov</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int CreateShortcut(string pName, string pSourceName)
        {
            try
            {
                IWshRuntimeLibrary.WshShellClass WshShell = new IWshRuntimeLibrary.WshShellClass();
                IWshRuntimeLibrary.IWshShortcut Shortcut = (IWshRuntimeLibrary.IWshShortcut)WshShell.CreateShortcut(pName);
                Shortcut.TargetPath = pSourceName;
                Shortcut.WorkingDirectory = IFileSystem.ExtractPath(pSourceName);
                Shortcut.Description = pSourceName;
                Shortcut.Save();
                return 0;
            }
            catch
            {
                return IFileSystem.FS_ERROR_UNKNOWN;
            }
        }
        /// <summary>Vytvorenie priecinku</summary>
        /// <param name="pName">nazov</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int CreateFolder(string pName)
        {
            return IFileSystem.CreateDirectory(IFileSystem.AppendToPath(CurrentPath, pName));
        }
        /// <summary>Vytvorenie priecinku</summary>
        /// <param name="pCurrentName">aktualny nazov</param>
        /// <param name="pNewName">novy nazov</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int RenameFolder(string pCurrentName, string pNewName)
        {
            return IFileSystem.RenameDirectory(pCurrentName, pNewName);
        }
        /// <summary>Premenovanie suboru</summary>
        /// <param name="pCurrentName">aktualny nazov</param>
        /// <param name="pNewName">novy nazov</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int RenameFile(string pCurrentName, string pNewName)
        {
            return IFileSystem.RenameFile(pCurrentName, pNewName);
        }
        /// <summary>Vytvorenie prazdneho suboru</summary>
        /// <param name="pName">nazov</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int CreateEmptyFile(string pName)
        {
            try
            {
                string FullFN = IFileSystem.AppendToPath(CurrentPath, pName);
                switch (IFileSystem.GetObjectType(FullFN))
                {
                    case IFileSystem.OBJECT_TYPE_FILE: return IFileSystem.FS_ERROR_FILE_EXISTS;
                    case IFileSystem.OBJECT_TYPE_DIRECTORY: return IFileSystem.FS_ERROR_DIRECTORY_EXISTS;
                    case IFileSystem.FS_ERROR_PATH_NOT_FOUND: break; // Nic sa nenaslo?
                    default: return IFileSystem.FS_ERROR_UNKNOWN;
                }

                System.IO.File.WriteAllText(FullFN, ""); // Vytvorim subor
                return 0;
            }
            catch
            {
                return IFileSystem.FS_ERROR_UNKNOWN;
            }
        }
        /// <summary>Property: CanCreateFileFromClipboard</summary>
        public override bool CanCreateFileFromClipboard
        {
            get
            {
                return IsCopyDestination;
            }
        }
        /// <summary>Ziskanie typu objektu</summary>
        /// <param name="pRelativeName">relativny nazov</param>
        /// <returns>OBJECT_TYPE_DIRECTORY, OBJECT_TYPE_FILE alebo kod chyby</returns>
        public override int GetItemType(string pRelativeName)
        {
            string FullFN = IFileSystem.AppendToPath(CurrentPath, pRelativeName);
            int R = IFileSystem.GetObjectType(FullFN);
            if ((R == IFileSystem.OBJECT_TYPE_DIRECTORY) || (R == IFileSystem.OBJECT_TYPE_FILE)) return R;
            if (R < 0) return R;
            return IFileSystem.FS_ERROR_PATH_NOT_FOUND;
        }

        /// <summary>Nastavenie zoznamu do modu zdroja kopirovania</summary>
        public override void BeginSourceCopyMode()
        {
            if (IFileSystem.IsReparseLink(FExpand_InitExpandPath)) FCopyModeBasePath = IFileSystem.GetRaparseLink(FExpand_InitExpandPath); // Ak je rep. link tak ziskam fyzicku adresu
            else FCopyModeBasePath = FExpand_InitExpandPath;
            FCopyModeBasePath = IFileSystem.AppendPathSeparator(FCopyModeBasePath); // Pridam posledny oddelovac

            FCopyMode_FileHandle = IntPtr.Zero;
            CopyMode_DataBuffer = core2.AllocateMemory(MAX_COPY_BUFFER_SIZE);
            FState = 2; // Nastavim stav
        }
        /// <summary>Uzatvorenie modu kopirovania</summary>
        public override void CloseCopyMode()
        {
            if (FCopyMode_FileHandle != IntPtr.Zero) core2.CloseLocalFile(FCopyMode_FileHandle); // Uzatvorim subor
            FCopyMode_FileHandle = IntPtr.Zero;
            if (FCopyMode_FileStream != null)
            {
                FCopyMode_FileStream.Close(); FCopyMode_FileStream.Dispose(); FCopyMode_FileStream = null;
            }
            if (CopyMode_DataBuffer != IntPtr.Zero) core2.FreeMemory(CopyMode_DataBuffer); // Zrusim buffer
            CopyMode_DataBuffer = IntPtr.Zero;

            FState = 0; // Zrusim mod
        }
        /// <summary>Vytvorenie relativnej cesty</summary>
        /// <param name="pPath">plna cesta</param>
        /// <param name="IsFolder">priznak ci to je priecinok</param>
        /// <param name="pProposal">navrh priznaku priecinku</param>
        /// <returns>relativna cesta</returns>
        public override string CopyMode_MakeRelative(string pPath, out bool IsFolder, bool pProposal = false)
        {
            IsFolder = true; 
            string P = IFileSystem.AppendPathSeparator(pPath); // Pripojim separator
            if (string.Compare(FCopyModeBasePath, 0, P, 0, FCopyModeBasePath.Length, true) != 0) return ""; // Chyba?

            switch (IFileSystem.GetObjectType(pPath)) // Ziskam typ objektu
            {
                case IFileSystem.OBJECT_TYPE_DIRECTORY: IsFolder = true; break;
                case IFileSystem.FS_ERROR_PATH_NOT_FOUND:
                case IFileSystem.OBJECT_TYPE_FILE: IsFolder = false; break;
                default: return "";
            }
            return IFileSystem.DeletePathSeparator(P).Substring(FCopyModeBasePath.Length); // Vratim relativnu cestu
        }
        /// <summary>Nastavenie zoznamu do modu zdroja kopirovania</summary>
        public override void BeginDestinationCopyMode()
        {
            if (IFileSystem.IsReparseLink(FExpand_InitExpandPath)) FCopyModeBasePath = IFileSystem.GetRaparseLink(FExpand_InitExpandPath); // Ak je rep. link tak ziskam fyzicku adresu
            else FCopyModeBasePath = FExpand_InitExpandPath;
            FCopyModeBasePath = IFileSystem.AppendPathSeparator(FCopyModeBasePath); // Pridam posledny oddelovac

            FState = 3; // Nastavim stav
        }
        /// <summary>Vytvorenie priecinku pri kopirovani</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <param name="pAttributes">atributy</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int CopyMode_MakeFolder(string pRelativePath, uint pAttributes)
        {
            string FullPath = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativePath);
            int R = IFileSystem.CreateFullDirectory(FullPath); // Volam vytvorenie priecinku
            switch (R)
            {
                case 0:
                case IFileSystem.FS_ERROR_DIRECTORY_EXISTS:
                    {
                        if (pAttributes != IWin32.INVALID_FILE_ATTRIBUTES) IWin32.Kernel32.SetFileAttributes(FullPath, pAttributes);
                        return R;
                    }
                default: return R;
            }
        }
        /// <summary>Vymazanie priecinku</summary>
        /// <param name="pRelativePath">relativny nazov</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int CopyMode_DeleteFolder(string pRelativePath)
        {
            string FullPath = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativePath);
            return IFileSystem.DeleteDirectory(FullPath); // Volam vymazanie
        }
        /// <summary>Vytvorenie zoznamu pre zdroj kopirovania</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>zoznam</returns>
        public override INodeList CopyMode_CreateSourceList(string pRelativePath)
        {
            INodeList L = INodeList.CreateNodeList(IFileSystem.AppendToPath(FCopyModeBasePath, pRelativePath)); // Vytvorim list
            return L;
        }
        /// <summary>Ziskanie atributov</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>atributy</returns>
        public override uint CopyMode_GetAttributes(string pRelativePath)
        {
                string FullFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativePath); // Vytvorim plny nazov
                return IWin32.Kernel32.GetFileAttributes(FullFN);
        }
        /// <summary>Ziskanie datumu zmeny</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>datum zmeny</returns>
        public override DateTime CopyMode_GetModifyDate(string pRelativePath)
        {
            try
            {
                string FullFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativePath); // Vytvorim plny nazov
                return System.IO.File.GetLastWriteTimeUtc(FullFN);
            }
            catch
            {
                return DateTime.Now;
            }
        }
        /// <summary>Ziskanie datumu vytvorenia</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>datum</returns>
        public override DateTime CopyMode_GetCreationDate(string pRelativePath)
        {
            try
            {
                string FullFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativePath); // Vytvorim plny nazov
                return System.IO.File.GetLastWriteTimeUtc(FullFN);
            }
            catch
            {
                return DateTime.Now;
            }
        }
        /// <summary>Ziskanie datumu posledneho pristupu</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>datum</returns>
        public override DateTime CopyMode_GetLastAccessDate(string pRelativePath)
        {
            try
            {
                string FullFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativePath); // Vytvorim plny nazov
                return System.IO.File.GetLastAccessTimeUtc(FullFN);
            }
            catch
            {
                return DateTime.Now;
            }
        }
        /// <summary>Ziskanie atributov</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>atributy</returns>
        public override uint CopyMode_GetAttributes()
        {
            return FCopyMode_FileAttributes;
        }
        /// <summary>Ziskanie datumu zmeny</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>datum zmeny</returns>
        public override DateTime CopyMode_GetModifyDate()
        {
            return FCopyMode_DModify;
        }
        /// <summary>Vytvorenie plnej cesty</summary>
        /// <param name="pPath">relativna cesta</param>
        /// <returns>plna cesta</returns>
        public override string CopyMode_MakeDestinationFullPath(string pRelative)
        {
            return IFileSystem.AppendToPath(FCopyModeBasePath, pRelative);
        }
        /// <summary>Otvorenie suboroveho streamu</summary>
        /// <param name="pRelative">relativne meno</param>
        /// <param name="pInfo">informacie o subore</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int CopyMode_OpenReadFile(string pRelative, INode pInfo = null)
        {
            if (FCopyMode_FileHandle != IntPtr.Zero) core2.CloseLocalFile(FCopyMode_FileHandle); // Uzatvorim subor
            FCopyMode_FileHandle = IntPtr.Zero;
            string FullFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelative); // Vytvorim plny nazov

            FCopyMode_FileHandle = core2.OpenLocalFileForRead(FullFN);
            if (FCopyMode_FileHandle == IntPtr.Zero) return IFileSystem.FS_ERROR_UNKNOWN;

            if (pInfo != null)
            {
                FCopyMode_DModify = pInfo.DLastModify;
                FCopyMode_FileAttributes = pInfo.Attributes;
                FCopyMode_FileSize = pInfo.Size;
            }
            else
            {
                try
                {
                    FCopyMode_DModify = System.IO.File.GetLastWriteTimeUtc(FullFN);
                }
                catch
                {
                    FCopyMode_DModify = DateTime.Now;
                }
                try
                {
                    FCopyMode_FileAttributes = (uint)System.IO.File.GetAttributes(FullFN);
                }
                catch
                {
                    FCopyMode_FileAttributes = IWin32.INVALID_FILE_ATTRIBUTES;
                }
                try
                {
                    FCopyMode_FileSize = (new System.IO.FileInfo(FullFN)).Length;
                }
                catch
                {
                    FCopyMode_FileSize = -1;
                }
            }
            FCopyMode_FileName = FullFN; // Ulozim nazov suboru
            return 0;
        }
        /// <summary>Uzatvorenie aktualne otvoreneho suboru pre citanie</summary>
        /// <param name="pDeleteAfterClose">priznak vymazania po uzatvoreni</param>
        public override void CopyMode_CloseReadFile(bool pDeleteAfterClose = false)
        {
            core2.CloseLocalFile(FCopyMode_FileHandle); // Uzatvorim subor
            FCopyMode_FileHandle = IntPtr.Zero;
            if (pDeleteAfterClose)
            {
                IFileSystem.DeleteFile(FCopyMode_FileName, true, true, true);
            }
        }
        /// <summary>Vytvorenie plnej cesty</summary>
        /// <param name="pPath">relativna cesta</param>
        /// <returns>plna cesta</returns>
        public override string CopyMode_MakeSourceFullPath(string pRelative)
        {
            return IFileSystem.AppendToPath(FCopyModeBasePath, pRelative);
        }
        /// <summary>Vytvorenie suboroveho streamu pre zapis</summary>
        /// <param name="pRelative">relativne meno</param>
        /// <param name="pAttributes">atributy noveho suboru</param>
        /// <param name="pCanOverwrite">priznak moznosti prepisania existujuceho suboru</param>
        /// <param name="pCanOverwriteAttr_ReadOnly">priznak moznosti prepisania existujuceho suboru s atributom readonly</param>
        /// <param name="pCanOverwriteAttr_Hidden">priznak moznosti prepisania existujuceho suboru s atributom hidden</param>
        /// <param name="pCanOverwriteAttr_System">priznak moznosti prepisania existujuceho suboru s atributom system</param>
        /// <param name="pModifyDate">datum modifikacie</param>
        /// <param name="pNativeStream">priznak pouzitia nativneho spracovania</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int CopyMode_CreateWriteFile(string pRelative, uint pAttributes, DateTime pModifyDate, bool pCanOverwrite = false, bool pCanOverwriteAttr_ReadOnly = false, bool pCanOverwriteAttr_Hidden = false, bool pCanOverwriteAttr_System = false, bool pNativeStream = false)
        {
            FCopyMode_FileAttributes = pAttributes; // Ulozim atributy
            FCopyMode_DModify = pModifyDate;

            string FullFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelative); // Vytvorim plny nazov
            switch (IFileSystem.GetObjectType(FullFN))
            {
                case IFileSystem.OBJECT_TYPE_FILE:
                    {
                        if (!pCanOverwrite) return IFileSystem.FS_ERROR_FILE_EXISTS;

                        uint Attr = IWin32.Kernel32.GetFileAttributes(FullFN);
                        if (Attr != IWin32.INVALID_FILE_ATTRIBUTES)
                        {
                            if ((!pCanOverwriteAttr_Hidden) | (!pCanOverwriteAttr_ReadOnly) | (!pCanOverwriteAttr_System))
                            {
                                if ((!pCanOverwriteAttr_ReadOnly) && ((Attr & IWin32.FILE_ATTRIBUTE_READONLY) != 0)) return IFileSystem.FS_ERROR_READ_ONLY_ATTRIBUTE;
                                if ((!pCanOverwriteAttr_System) && ((Attr & IWin32.FILE_ATTRIBUTE_SYSTEM) != 0)) return IFileSystem.FS_ERROR_SYSTEM_ATTRIBUTE;
                                if ((!pCanOverwriteAttr_Hidden) && ((Attr & IWin32.FILE_ATTRIBUTE_HIDDEN) != 0)) return IFileSystem.FS_ERROR_HIDDEN_ATTRIBUTE;
                            }
                            if (!IWin32.Kernel32.SetFileAttributes(FullFN, IWin32.FILE_ATTRIBUTE_NORMAL)) return IFileSystem.FS_ERROR_ACCESS_DENIED;
                        }
                    } break;
                case IFileSystem.OBJECT_TYPE_DIRECTORY: return IFileSystem.FS_ERROR_DIRECTORY_EXISTS;
            }
            FCopyMode_FileName = FullFN; // Ulozim nazov
            if (pNativeStream)
            {
                FCopyMode_FileHandle = IntPtr.Zero;
                try
                {
                    FCopyMode_FileStream = new System.IO.FileStream(FullFN, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None); // Vytvorim stream
                    return 0; // OK
                }
                catch
                {
                    return IFileSystem.FS_ERROR_UNKNOWN;
                }
            }
            else
            {
                FCopyMode_FileStream = null;
                FCopyMode_FileHandle = core2.CreateLocalFile(FullFN); // Vytvorim subor
                return FCopyMode_FileHandle == IntPtr.Zero ? IFileSystem.FS_ERROR_UNKNOWN : 0;
            }
        }
        /// <summary>Uzatvorenie aktualne otvoreneho suboru pre zapis</summary>
        /// <param name="pDeleteAfterClose">priznak vymazania suboru po uzatvoreni</param>
        public override void CopyMode_CloseWriteFile(bool pDeleteAfterClose = false)
        {
            if (FCopyMode_FileHandle != IntPtr.Zero) core2.CloseLocalFile(FCopyMode_FileHandle); // Uzatvorim subor
            FCopyMode_FileHandle = IntPtr.Zero;
            if (FCopyMode_FileStream != null) FCopyMode_FileStream.Close();
            FCopyMode_FileStream = (System.IO.FileStream)ICore.DisposeObject(FCopyMode_FileStream);

            if (pDeleteAfterClose)
            {
                IFileSystem.DeleteFile(FCopyMode_FileName, true, true, true); // Zmazem subor
            }
            else
            {
                try
                {
                    System.IO.File.SetLastWriteTime(FCopyMode_FileName, FCopyMode_DModify);
                }
                catch
                {
                }
                IWin32.Kernel32.SetFileAttributes(FCopyMode_FileName, FCopyMode_FileAttributes);
            }
        }
        /// <summary>Nacitanie obsahu</summary>
        /// <param name="pMaxLength">max. dlzka</param>
        /// <param name="pResultBuffer">vysledny buffer alebo null pre interny</param>
        /// <returns>pocet nacitanych bajtov alebo kod chyby</returns>
        public override int CopyMode_ReadFile(int pMaxLength, IntPtr pResultBuffer)
        {
            return core2.ReadFromLocalFile(FCopyMode_FileHandle, pResultBuffer, pMaxLength);
        }
        /// <summary>Zapisanie obsahu</summary>
        /// <param name="pBuffer">buffer</param>
        /// <param name="pStart">zaciatok</param>
        /// <param name="pLength">dlzka</param>
        /// <returns>pocet nacitanych bajtov alebo kod chyby</returns>
        public override int CopyMode_WriteFile(IntPtr pBuffer, int pStart, int pLength)
        {
            return core2.WriteToLocalFile(FCopyMode_FileHandle, pBuffer, pLength);
        }
        /// <summary>Rychly presun priecinku</summary>
        /// <param name="pRelativeName">relativny nazov</param>
        /// <param name="pDestinationPath">cielova cesta</param>
        /// <returns>0 - OK alebo kod chyby</returns>
        public override int CopyMode_FastMoveFolder(string pRelativeName, string pDestinationPath)
        {
            if (!SupportFastMoveToPath(pDestinationPath)) return -1; // Nepodporovane

            switch (IFileSystem.GetObjectType(pDestinationPath)) // Test existencie ciela
            {
                case IFileSystem.FS_ERROR_PATH_NOT_FOUND: break;
                default: return -1;
            }
            string SourceFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativeName); // Ziskam nazov zdroja
            return IWin32.Kernel32.MoveFile(SourceFN, pDestinationPath) != 0 ? 0 : -1; // Presuniem
        }
        /// <summary>Rychly presun suboru</summary>
        /// <param name="pRelativeName">relativny nazov</param>
        /// <param name="pDestinationPath">cielova cesta</param>
        /// <returns>0 - OK alebo kod chyby</returns>
        public override int CopyMode_FastMoveFile(string pRelativeName, string pDestinationPath)
        {
            if (!SupportFastMoveToPath(pDestinationPath)) return -1; // Nepodporovane

            switch (IFileSystem.GetObjectType(pDestinationPath)) // Test existencie ciela
            {
                case IFileSystem.FS_ERROR_PATH_NOT_FOUND: break;
                default: return -1;
            }
            string SourceFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativeName); // Ziskam nazov zdroja
            return IWin32.Kernel32.MoveFile(SourceFN, pDestinationPath) != 0 ? 0 : -1; // Presuniem
        }
        /// <summary>Ziskanie dlzky aktivneho suboru</summary>
        /// <returns>dlzka</returns>
        public override long CopyMode_GetSize()
        {
            return FCopyMode_FileSize;
        }
        /// <summary>Ziskanie dlzky</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>dlzka</returns>
        public override long CopyMode_GetSize(string pRelativePath)
        {
            try
            {
                string FullFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativePath); // Vytvorim plny nazov
                return (new System.IO.FileInfo(FullFN)).Length;
            }
            catch
            {
                return -1;
            }
        }
        /// <summary>Zapisanie obsahu</summary>
        /// <param name="pBuffer">buffer</param>
        /// <param name="pStart">zaciatok</param>
        /// <param name="pLength">dlzka</param>
        /// <returns>pocet nacitanych bajtov alebo kod chyby</returns>
        public override int CopyMode_WriteFile(byte[] pBuffer, int pStart, int pLength)
        {
            try
            {
                FCopyMode_FileStream.Write(pBuffer, pStart, pLength); // Zapisem
                return 0;
            }
            catch
            {
                return IFileSystem.FS_ERROR_UNKNOWN;
            }
        }
        /// <summary>Zapisanie retazca do textoveho suboru v ramci modu kopirovania</summary>
        /// <param name="pRelativeName">relativny nazov</param>
        /// <param name="pData">data suboru</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int CopyMode_WriteTextFile(string pRelativeName, string pData)
        {
            string FullFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativeName); // Vytvorim plny nazov
            try
            {
                System.IO.File.WriteAllText(FullFN, pData); // Zapisem do suboru
                return 0; // Vsetko OK
            }
            catch
            {
                return IFileSystem.FS_ERROR_UNKNOWN;
            }
        }
        /// <summary>Nacitanie obsahu textoveho suboru</summary>
        /// <param name="pRelativeName">nazov</param>
        /// <param name="pMaxLength">max. dlzka alebo -1 pre cely obsah</param>
        /// <param name="Result">vysledok</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int CopyMode_ReadFromTextFile(string pRelativeName, int pMaxLength, out string Result)
        {
            Result = "";
            string FullFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativeName); // Vytvorim plny nazov

            if (pMaxLength == -1) // Vratit cely obsah?
            {
                try
                {
                    Result = System.IO.File.ReadAllText(FullFN);
                    return 0; // Vsetko OK
                }
                catch
                {
                    return -1; // Chyba
                }
            }

            try
            {
                using (System.IO.StreamReader R = new System.IO.StreamReader(FullFN)) // Otvorim stream
                {
                    char[] Data = new char[pMaxLength]; // Alokujem pamat
                    int C = R.ReadBlock(Data, 0, pMaxLength); // Citam data
                    Result = new string(Data, 0, C);
                    Data = null;
                    return 0; // Vsetko OK
                }
            }
            catch
            {
                return -1; // Chyba
            }
        }
        /// <summary>Vytvorenie streamu pre zapis</summary>
        /// <param name="pRelativeName">nazov</param>
        /// <param name="pCanOverwrite">priznak moznosti prepisania existujuceho suboru</param>
        /// <param name="pCanOverwriteAttr_ReadOnly">priznak moznosti prepisania existujuceho suboru s atributom readonly</param>
        /// <param name="pCanOverwriteAttr_Hidden">priznak moznosti prepisania existujuceho suboru s atributom hidden</param>
        /// <param name="pCanOverwriteAttr_System">priznak moznosti prepisania existujuceho suboru s atributom system</param>
        /// <returns>stream alebo null</returns>
        public override System.IO.Stream CopyMode_CreateStreamForWrite(string pRelativeName, out int pErrorCode, bool pCanOverwrite = false, bool pCanOverwriteAttr_ReadOnly = false, bool pCanOverwriteAttr_Hidden = false, bool pCanOverwriteAttr_System = false)
        {
            pErrorCode = 0; 
            string FullFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativeName); // Vytvorim plny nazov
            switch (IFileSystem.GetObjectType(FullFN))
            {
                case IFileSystem.OBJECT_TYPE_FILE:
                    {
                        if (!pCanOverwrite)
                        {
                            pErrorCode = IFileSystem.FS_ERROR_FILE_EXISTS;
                            return null;
                        }

                        uint Attr = IWin32.Kernel32.GetFileAttributes(FullFN);
                        if (Attr != IWin32.INVALID_FILE_ATTRIBUTES)
                        {
                            if ((!pCanOverwriteAttr_Hidden) | (!pCanOverwriteAttr_ReadOnly) | (!pCanOverwriteAttr_System))
                            {
                                if ((!pCanOverwriteAttr_ReadOnly) && ((Attr & IWin32.FILE_ATTRIBUTE_READONLY) != 0))
                                {
                                    pErrorCode = IFileSystem.FS_ERROR_READ_ONLY_ATTRIBUTE;
                                    return null;
                                }
                                if ((!pCanOverwriteAttr_System) && ((Attr & IWin32.FILE_ATTRIBUTE_SYSTEM) != 0))
                                {
                                    pErrorCode = IFileSystem.FS_ERROR_SYSTEM_ATTRIBUTE;
                                    return null;
                                }
                                if ((!pCanOverwriteAttr_Hidden) && ((Attr & IWin32.FILE_ATTRIBUTE_HIDDEN) != 0))
                                {
                                    pErrorCode = IFileSystem.FS_ERROR_HIDDEN_ATTRIBUTE;
                                    return null;
                                }
                            }
                            if (!IWin32.Kernel32.SetFileAttributes(FullFN, IWin32.FILE_ATTRIBUTE_NORMAL))
                            {
                                pErrorCode = IFileSystem.FS_ERROR_ACCESS_DENIED;
                                return null;
                            }
                        }
                    } break;
                case IFileSystem.OBJECT_TYPE_DIRECTORY:
                    {
                        pErrorCode = IFileSystem.FS_ERROR_DIRECTORY_EXISTS;
                        return null;
                    }
            }

            try
            {
                return new System.IO.FileStream(FullFN, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.Delete); // Vytvorim stream
            }
            catch
            {
                pErrorCode = IFileSystem.FS_ERROR_UNKNOWN;
                return null;
            }
        }
        /// <summary>Uzatvorenie streamu pre zapis</summary>
        /// <param name="pStream">stream</param>
        /// <param name="pDeleteAfterClose">priznak vymazania po uzatvoreni</param>
        public override void CopyMode_CloseStreamForWrite(System.IO.Stream pStream, bool pDeleteAfterClose)
        {
            if (pStream == null) return; // Neplatny vstup?
            string FN = ((System.IO.FileStream)pStream).Name; // Ulozim meno suboru
            pStream.Close(); pStream.Dispose(); pStream = null; // Zrusim stream

            if (pDeleteAfterClose) IFileSystem.DeleteFile(FN); // Vymazem subor ak je poziadavka
        }
        /// <summary>Nacitanie obsahu</summary>
        /// <param name="pMaxLength">max. dlzka</param>
        /// <param name="pResultBuffer">vysledny buffer alebo null pre interny</param>
        /// <returns>pocet nacitanych bajtov alebo kod chyby</returns>
        public override int CopyMode_ReadFile(int pMaxLength, byte[] pResultBuffer)
        {
            int C = CopyMode_ReadFile(pMaxLength, CopyMode_DataBuffer);
            if (C <= 0) return C; // Chyba alebo koniec?

            for (int i = 0; i < C; i++) pResultBuffer[i] = System.Runtime.InteropServices.Marshal.ReadByte(CopyMode_DataBuffer, i);
            return C;
        }
        /// <summary>Vytvorenie streamu pre zapis</summary>
        /// <param name="pRelativeName">nazov</param>
        /// <param name="pCanOverwrite">priznak moznosti prepisania existujuceho suboru</param>
        /// <param name="pCanOverwriteAttr_ReadOnly">priznak moznosti prepisania existujuceho suboru s atributom readonly</param>
        /// <param name="pCanOverwriteAttr_Hidden">priznak moznosti prepisania existujuceho suboru s atributom hidden</param>
        /// <param name="pCanOverwriteAttr_System">priznak moznosti prepisania existujuceho suboru s atributom system</param>
        /// <returns>stream alebo null</returns>
        public override System.IO.Stream CopyMode_OpenStreamForRead(string pRelativeName, out int pErrorCode)
        {
            pErrorCode = 0;
            string FullFN = IFileSystem.AppendToPath(FCopyModeBasePath, pRelativeName); // Vytvorim plny nazov
            try
            {
                return new System.IO.FileStream(FullFN, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Delete); // Vytvorim stream
            }
            catch
            {
                pErrorCode = IFileSystem.FS_ERROR_UNKNOWN;
                return null;
            }
        }
        /// <summary>Uzatvorenie streamu pre zapis</summary>
        /// <param name="pStream">stream</param>
        /// <param name="pDeleteAfterClose">priznak vymazania po uzatvoreni</param>
        public override void CopyMode_CloseStreamForRead(System.IO.Stream pStream, bool pDeleteAfterClose)
        {
            if (pStream == null) return; // Neplatny vstup?
            string FN = ((System.IO.FileStream)pStream).Name; // Ulozim meno suboru
            pStream.Close(); pStream.Dispose(); pStream = null; // Zrusim stream

            if (pDeleteAfterClose) IFileSystem.DeleteFile(FN); // Vymazem subor ak je poziadavka
        }
    }
}
